package com.sxpi.zixun.service.adminpermission;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxpi.zixun.bo.AdminPermissionBo;
import com.sxpi.zixun.common.enums.ResultStatusEnum;
import com.sxpi.zixun.common.utils.fn.asserts.Vsserts;
import com.sxpi.zixun.mapper.AdminPermissionMapper;
import com.sxpi.zixun.pojo.AdminPermission;
import com.sxpi.zixun.vo.StatusUpdateVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 董伟豪
 * @Date: 2022/8/27 16:15
 */
@Service
@Slf4j
public class IAdminPermissionServiceImpl extends ServiceImpl<AdminPermissionMapper, AdminPermission> implements IAdminPermissionService{

    /**
     * 查询分类的接口信息-tree
     * 这里是递归查询所有的权限，让角色去授予权限使用
     * @return
     */
    @Override
    public List<AdminPermission> findAdminPermissionTree() {
        LambdaQueryWrapper<AdminPermission> adminPermissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        adminPermissionLambdaQueryWrapper.eq(AdminPermission::getStatus,1);
        List<AdminPermission> allList = this.list(adminPermissionLambdaQueryWrapper);
        // 获取所有的根节点
        List<AdminPermission> rootList = allList.stream().filter(category -> {
            return category.getPid().equals(0L);
        }).sorted((a, b) -> a.getSorted() - b.getSorted()).collect(Collectors.toList());
        // 查询所有非根节点
        List<AdminPermission> subList = allList.stream().filter(category -> {
            return !category.getPid().equals(0L);
        }).collect(Collectors.toList());
        // 循环根节点去subList去找对应的子节点
        // 这里循环的是root，每次循环都会去携带subList，我想根据一个根节点去找他里面符合这个的所有的子节点
        rootList.forEach(root -> buckForback(root, subList));
        return rootList;
    }

    private void buckForback(AdminPermission root, List<AdminPermission> subList) {
        // 所有子节点进行一个遍历，我需要的是属于父节点的全部子节点
        List<AdminPermission> childrenList = subList.stream().filter(category -> {
            return category.getPid().equals(root.getId());
        }).sorted((a, b) -> a.getSorted() - b.getSorted()).collect(Collectors.toList());
        // 如果你当前没一个子集，初始化一个空数组
        if(!CollectionUtils.isEmpty(childrenList)){
            root.setChildren(childrenList);
            // 再次递归即可
            // childrenList虽然是一个集合，但是我这个集合下面肯定还会有他的子节点，所以我再去把  这个  集合中的每一个元素进行遍历，去在所有子元素中寻找匹配的
            childrenList.forEach(category->{
                buckForback(category,subList);
            });
        }else{
            root.setChildren(new ArrayList<>());
        }
    }

    /**
     * 查询左边菜单栏
     * @return
     */
    @Override
    public List<AdminPermission> findAdminPermissionMenuTree() {
        LambdaQueryWrapper<AdminPermission> adminMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
        adminMenuLambdaQueryWrapper.eq(AdminPermission::getStatus,1);
        adminMenuLambdaQueryWrapper.eq(AdminPermission::getIsdelete,0);
        adminMenuLambdaQueryWrapper.eq(AdminPermission::getType,1);
        // 所有有效数据
        List<AdminPermission> allList = this.list(adminMenuLambdaQueryWrapper);
        // 查看全部根节点，sorted 进行排序
        List<AdminPermission> rootMenuList = allList.stream().filter(menu -> {
            return menu.getPid().equals(0L);
        }).sorted((a,b)->{
            return a.getSorted() - b.getSorted();
        }).collect(Collectors.toList());
        // 查询 各个父亲的子节点(这个stream说真的和foreach一样)
        rootMenuList = rootMenuList.stream().peek(rootMenu -> {
            buckForbackMenu(rootMenu,allList);
        }).collect(Collectors.toList());
        return rootMenuList;
    }

    /**
     * 保存&修改后台权限管理
     * @param adminpermission
     * @return
     */
    @Override
    public AdminPermissionBo saveUpdateAdminPermission(AdminPermission adminpermission) {
        // pid默认赋值的是空
        Vsserts.isNullEx(adminpermission.getPid(), ResultStatusEnum.NULL_PID);
        boolean flag = this.saveOrUpdate(adminpermission);
        return flag ? tranferBo(adminpermission,AdminPermissionBo.class) : null;
    }

    /**
     * 根据id删除后台权限管理
     * @param permissionId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteAdminPermissionById(Long permissionId) {
        // 根据id删除中间表绑定的数据
        this.baseMapper.deleteByPermissionId(permissionId);
        // 删除自己
        boolean b = this.removeById(permissionId);
        return b ? 1 : 0;
    }

    /**
     * 用于状态更新
     * @param statusUpdateVo
     * @return
     */
    @Override
    public boolean updateAdminPermission(StatusUpdateVo statusUpdateVo) {
        AdminPermission adminPermission = tranferBo(statusUpdateVo, AdminPermission.class);
        return this.updateById(adminPermission);
    }

    private void buckForbackMenu(AdminPermission rootMenu, List<AdminPermission> allList) {
        // 查询出来所有的子项，并且赋值到每个根节点下面
        List<AdminPermission> childrenMenuList = allList.stream().
                filter(menu -> {
                    return menu.getPid().equals(rootMenu.getId());
                }).sorted((a,b)->{
                    return a.getSorted() - b.getSorted();
                }).collect(Collectors.toList());
        // 为了防止空集合，让json转换的时候由[]，方便后续的判断长度
        if (CollectionUtils.isEmpty(childrenMenuList)) {
            // 把找到的子元素进行修改
            rootMenu.setChildren(new ArrayList<>());
        }else{
            // 把找到的子元素进行修改
            rootMenu.setChildren(childrenMenuList);
            childrenMenuList.forEach(childrenMenu->{
                buckForbackMenu(childrenMenu,allList);
            });
        }
        // return rootMenu 这里被peek了
    }
}
